<!-- 本组件提供自动上传一个文件到服务器的功能，用于上传单个附件
上传成功后，服务器返回的完整数据格式是：
{
  ExtName: ".jpg"
  FileNameClient: "QQ图片20211209084707.jpg"
  Message: "OK"
  MimeType: "image/jpeg"
  Url: "/upload-file/image/2022/01/03/20220103110722323_QQ图片20211209084707.jpg"
  UrlThumb: "/upload-file/image/2022/01/03/20220103110722323_QQ图片20211209084707_tn.jpg"
  UrlWm: ""
  uuid: "c92edbb2d72b4963a88dc36c4f99f45f"
}

以文章标题图为例，上传完成后，返回给调用方的数据格式是：
{
  Url: "/upload-file/image/2022/01/03/20220103110722323_QQ图片20211209084707.jpg"
  UrlThumb: "/upload-file/image/2022/01/03/20220103110722323_QQ图片20211209084707_tn.jpg"
  UrlWm: ""
  uuid: "c92edbb2d72b4963a88dc36c4f99f45f"
}

使用方法：
1、导入本组件
import TheUploader from '@/components/UploadFile2Local'
2、定义本组件
components: { TheUploader }
3、html中调用本组件
<TheUploader @setUploadResult="getUploadResult($event)" />
4、父组件中定义获取上传结果的方法
getUploadResult(val) {
  console.log('val:', val)
  formData.urlTitlePic = JSON.stringify(val)
}
-->
<template>
  <div class="wrapper-uploader">
    <el-upload
      ref="refUploader"
      :action="urlActionRemote"
      :data="paramsJson"
      :headers="headerJwt"
      :multiple="false"
      :show-file-list="false"
      :before-upload="onBeforeUpload"
      :on-success="onSuccess"
      :on-error="onError"
    >
      <el-button type="primary" icon="Upload">选择附件上传</el-button>
    </el-upload>
  </div>
</template>

<script>
import { getJwtFromCookie } from '@/utils/jwt'
import { getLStorageObj } from '@/utils/web-storage'

import { isAllowedFile, isAllowedSizeByExt, getSizeLimitByExt } from '@/utils/file'
import { toastSuccess, toastError } from '@/utils/toast'

import router from '@/router'
import { defineComponent, ref, onMounted, computed } from 'vue'
export default defineComponent({
  name: 'UploadFileCom',
  props: {
    adminId: {
      type: Number,
      default: 0,
    },
    taskId: {
      type: Number,
      default: 0,
    },
  },
  emit: ['update:setUploadResult'],
  setup(props, { emit }) {
    const uploadConfig = ref(null)
    // 执行上传到服务器的action的url
    const urlActionRemote = ref(process.env.VUE_APP_URL_UPLOAD_ACTION)

    const headerJwt = computed(() => {
      return { authorization: 'Bearer ' + getJwtFromCookie() }
    })
    const paramsJson = computed(() => {
      return { AdminId: props.adminId, TaskId: props.taskId, FormData: null }
    })

    // 获取上传设置
    const getConfigUpload = () => {
      uploadConfig.value = getLStorageObj('UploadConfig')
      // 检验上传配置是否已设置，如果没有，跳回登录页
      if (!uploadConfig.value) {
        toastError('读取上传配置出错！请重新登录')
        router.push({ path: '/login' })
      }
    }

    // 自动上传时，在上传前进行格式校验和大小校验
    const onBeforeUpload = (rawFile) => {
      console.log('onBeforeUpload() rawFile', rawFile)
      // 验证格式
      if (!isAllowedFile(rawFile, uploadConfig.value.allowedExt)) {
        toastError('文件 [ ' + rawFile.name + ' ] 的格式不正确!')
        return false
      }
      // 验证大小
      if (!isAllowedSizeByExt(rawFile, uploadConfig.value)) {
        const msg =
          '文件 [ ' + rawFile.name + ' ] 的大小不能超过' + getSizeLimitByExt(rawFile, uploadConfig.value) + 'K!'
        toastError(msg)
        return false
      }
      return true
    }
    // 文件自动上传成功时的钩子
    const onSuccess = (response, file) => {
      console.log('onSuccess() response：', response)
      if (response && response.data.Message === 'OK') {
        // 上传成功
        const uploadResult = response.data
        const returnObj = {
          uuid: '',
          url: '',
          urlThumb: '',
          urlWm: '',
        }
        returnObj.uuid = uploadResult.uuid
        // 上传成功，必有 Url，但是不一定有 UrlThumb 和 UrlWm
        returnObj.url = uploadResult.Url
        returnObj.urlThumb = uploadResult.UrlThumb
        returnObj.urlWm = uploadResult.UrlWm
        // if (uploadResult.UrlThumb && uploadResult.UrlThumb.length > 0) {
        //   returnObj.urlThumb = uploadResult.UrlThumb
        // }
        // if (uploadResult.UrlWm && uploadResult.UrlWm.length > 0) {
        //   returnObj.urlWm = uploadResult.UrlWm
        // }
        returnUploadResult(returnObj)
        toastSuccess('上传成功！')
      } else {
        if (response.data.message) {
          toastError(response.data.message)
        } else {
          toastError('服务器错误！上传' + file.name + '失败！')
        }
        // 上传失败，返回空对象
        returnUploadResult({})
      }
    }
    // 文件上传失败时的钩子
    const onError = (err) => {
      console.log('onError() err：', err)
      // clog('onError 的 err:', err)
      toastError(err)
    }

    const returnUploadResult = (val) => {
      console.log('returnUploadResult() val', val)
      // 调用本组件时，设置 @setUploadResult="getUploadResult($event)"
      // 定义一个名称为 setUploadResult 的方法，方法的参数值就是这里返回的上传结果
      emit('setUploadResult', val)
    }

    onMounted(() => {
      getConfigUpload()
    })

    return {
      uploadConfig,
      urlActionRemote,
      headerJwt,
      paramsJson,
      getConfigUpload,
      onBeforeUpload,
      onSuccess,
      onError,
      returnUploadResult,
    }
  },
})
</script>

<style lang="scss" scoped></style>
